﻿#region zh-CHS 2006 - 2007 DemoSoft 团队 | en 2006 - 2007 DemoSoft Team

//     NOTES
// ---------------
//
// This file is a part of the G.O.S.E(Game Online Server Engine) for .NET.
//
//                 2006-2007 DemoSoft Team
//
//
// First Version : by H.Q.Cai - mailto:caihuanqing@hotmail.com

/***************************************************************************
 *
 *   This program is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU Lesser General Public License as published
 *   by the Free Software Foundation; either version 2.1 of the License, or
 *   (at your option) any later version.
 *
 ***************************************************************************/

#region zh-CHS 包含名字空间 | en Include namespace
using System;
using System.Text;
using System.Threading;
using System.Reflection;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.Serialization;
using Demo_G.O.S.E.ServerEngine.Map;
using Demo_G.O.S.E.ServerEngine.Util;
using Demo_G.O.S.E.ServerEngine.Item;
using Demo_G.O.S.E.ServerEngine.Skill;
using Demo_G.O.S.E.ServerEngine.Guild;
using Demo_G.O.S.E.ServerEngine.World;
using Demo_G.O.S.E.ServerEngine.Common;
using Demo_G.O.S.E.ServerEngine.Network;
using Demo_G.O.S.E.ServerEngine.Treasure;
using System.Diagnostics;
#endregion

namespace Demo_G.O.S.E.ServerEngine.Creature
{
    // 人物的信息
    //////////////////////////////////////////////////////////////////////////
    // 人物的种族
    // 人物的状态
    // 人物的抗性
    // 人物的信息
    // 人物的道具(包裹&身上)

    // 人物的动作
    //////////////////////////////////////////////////////////////////////////
    // 人物的移动
    // 人物的说话
    // 人物用道具
    // 人物的死亡
    // 人物的复活(NPC/怪物-刷出)

    // 人物的AI
    //////////////////////////////////////////////////////////////////////////
    // 人物的AI(移动/说话/攻击/防御/做任务)
    // 人物的普通(攻击/防御)
    // 人物的技能(攻击/增益/诅咒)
    // 人物的魔法(攻击/增益/诅咒)

    // 人物掉落的道具(玩家/NPC-可不掉落)
    // 人物可用的道具
    // 人物可见的范围
    // 
    // 
    // 

    /// <summary>
    /// Base class representing players, npcs, and creatures.
    /// </summary>
    public class BaseCreature : IEntity, IComparable, IComparable<BaseCreature>
    {
        #region zh-CHS 构造和初始化和清理 | en Constructors and Initializers and Dispose
        /// <summary>
        /// 构造
        /// </summary>
        public BaseCreature()
        {
            DefaultDeltaInit();
        }

        /// <summary>
        /// 构造
        /// </summary>
        /// <param name="serial">唯一序号</param>
        public BaseCreature( Serial serial )
        {
            m_Serial = serial;
            DefaultDeltaInit();
        }

        #region zh-CHS 人物的初始化 | en
        /// <summary>
        /// 缺省的初始化人物
        /// </summary>
        protected virtual void DefaultDeltaInit()
        {
        }
        #endregion

        #endregion

        #region zh-CHS 共有属性 | en Public Properties

        #region zh-CHS X属性 | en Public Properties

        /// <summary>
        /// 人物所在的X坐标点
        /// </summary>
        [CommandProperty( AccessLevel.Counselor, AccessLevel.GameMaster )]
        public long X
        {
            get { return m_Location.X; }
            set { UpdateMobile( UpdateBaseMobileValue.X, value ); }
        }

        #endregion

        #region zh-CHS Y属性 | en Public Properties

        /// <summary>
        /// 人物所在的Y坐标点
        /// </summary>
        [CommandProperty( AccessLevel.Counselor, AccessLevel.GameMaster )]
        public long Y
        {
            get { return m_Location.Y; }
            set { UpdateMobile( UpdateBaseMobileValue.Y, value ); }
        }

        #endregion

        #region zh-CHS Z属性 | en Public Properties

        /// <summary>
        /// 人物所在的Z坐标点
        /// </summary>
        [CommandProperty( AccessLevel.Counselor, AccessLevel.GameMaster )]
        public long Z
        {
            get { return m_Location.Z; }
            set { UpdateMobile( UpdateBaseMobileValue.Z, value ); }
        }

        #endregion

        #region zh-CHS Location属性 | en Public Properties

        #region zh-CHS 私有成员变量 | en Private Member Variables
        /// <summary>
        /// 人物所在地图的位置
        /// </summary>
        private Point3D m_Location = new Point3D();
        #endregion
        /// <summary>
        /// 人物所在地图的位置
        /// </summary>
        [CommandProperty( AccessLevel.Counselor, AccessLevel.GameMaster )]
        public Point3D Location
        {
            get { return m_Location; }
            set { UpdateMobile( UpdateBaseMobileValue.Location, value ); }
        }

        #region zh-CHS 人物的移动 | en

        #region zh-CHS 保护方法 | en Protected Methods
        /// <summary>
        /// 人物的移动方向时
        /// </summary>
        /// <param name="d"></param>
        /// <returns></returns>
        protected virtual bool OnBeforeMoveTo( Point3D newLocation )
        {
            return true;
        }

        /// <summary>
        /// 人物的移动之后调用
        /// </summary>
        /// <param name="oldLocation"></param>
        protected virtual void OnAfterMoveTo( Point3D oldLocation )
        {
        }

        /// <summary>
        /// 人物的移动方向时
        /// </summary>
        /// <param name="d"></param>
        /// <returns></returns>
        protected virtual bool OnBeforeSetLocation( Point3D newLocation )
        {
            return true;
        }

        /// <summary>
        /// 人物的移动之后调用
        /// </summary>
        /// <param name="oldLocation"></param>
        protected virtual void OnAfterSetLocation( Point3D oldLocation )
        {
        }

        /// <summary>
        /// 当前的地图改变
        /// </summary>
        /// <param name="oldBaseMap"></param>
        protected virtual bool OnBeforeMoveToWorld( Point3D newLocation, BaseMap newBaseMap )
        {
            return true;
        }

        /// <summary>
        /// 当前的地图改变
        /// </summary>
        /// <param name="oldBaseMap"></param>
        protected virtual void OnAfterMoveToWorld( Point3D oldLocation, BaseMap oldBaseMap )
        {
        }
        #endregion

        #region zh-CHS 内部保护方法 | en Protected Internal Methods
        /// <summary>
        /// 地图点激活
        /// </summary>
        protected internal virtual void OnSectorActivate()
        {
        }

        /// <summary>
        /// 地图点不激活
        /// </summary>
        protected internal virtual void OnSectorDeactivate()
        {
        }
        #endregion

        #region zh-CHS 共有方法 | en Public Methods
        /// <summary>
        /// 人物的移动方向
        /// </summary>
        /// <param name="d"></param>
        /// <returns></returns>
        public bool MoveTo( Point3D newLocation )
        {
            if ( m_Deleted || m_BaseMap == null || m_BaseMap == BaseMap.NullMap )
                return false;

            BaseCreatureDelta l_MobileDelta = m_MobileDelta as BaseCreatureDelta;
            if ( l_MobileDelta == null )
            {
                Debug.WriteLine( "BaseMobile.MoveTo(...) - l_MobileDelta == null error!" );
                return false;
            }

            //MovementEventArgs l_EventArgs = MovementEventArgs.Instance( this, newLocation );
            //if ( l_EventArgs == null )
            //{
            //    Debug.WriteLine( "BaseMobile.InternalOnMove(...) - l_EventArgs == null error!" );

            //    return false;
            //}

            //EventSink.InvokeMovement( l_EventArgs );
            //bool l_bReturn = !l_EventArgs.Blocked;

            //l_EventArgs.Release();

            //if ( l_bReturn == false )
            //    return false;

            Point3D oldLocation = m_Location;

            if ( OnBeforeMoveTo( newLocation ) == false )
                return false;
            else
            {
                if ( UpdateMobile( UpdateBaseMobileValue.Location, newLocation ) == false )
                    return false;
            }

            m_BaseMap.OnMove( oldLocation, this );

            l_MobileDelta.UpdateMoveToCall();
            if ( l_MobileDelta.IsDeltaMoveToCall )
                UpdateDelta();

            OnAfterMoveTo( oldLocation );

            return true;
        }

        /// <summary>
        /// 移动到当前地图的某个点
        /// </summary>
        /// <param name="newLocation"></param>
        /// <param name="isTeleport"></param>
        public bool SetLocation( Point3D newLocation )
        {
            if ( m_Deleted || m_BaseMap == null || m_BaseMap == BaseMap.NullMap )
                return false;

            BaseCreatureDelta l_MobileDelta = m_MobileDelta as BaseCreatureDelta;
            if ( l_MobileDelta == null )
            {
                Debug.WriteLine( "BaseMobile.SetLocation(...) - l_MobileDelta == null error!" );
                return false;
            }

            Point3D oldLocation = m_Location;

            if ( OnBeforeSetLocation( newLocation ) == false )
                return false;
            else
            {
                if ( UpdateMobile( UpdateBaseMobileValue.Location, newLocation ) == false )
                    return false;
            }

            m_BaseMap.OnMove( oldLocation, this );

            l_MobileDelta.UpdateSetLocationCall();
            if ( l_MobileDelta.IsDeltaSetLocationCall )
                UpdateDelta();

            OnAfterSetLocation( oldLocation );

            return true;
        }

        /// <summary>
        /// 移动到世界的某地图的某个点
        /// </summary>
        /// <param name="newLocation"></param>
        /// <param name="map"></param>
        public bool MoveToWorld( Point3D newLocation, BaseMap newBaseMap )
        {
            if ( m_Deleted || m_BaseMap == null || m_BaseMap == BaseMap.NullMap || newBaseMap == null || newBaseMap == BaseMap.NullMap )
                return false;

            BaseCreatureDelta l_MobileDelta = m_MobileDelta as BaseCreatureDelta;
            if ( l_MobileDelta == null )
            {
                Debug.WriteLine( "BaseMobile.MoveToWorld(...) - l_MobileDelta == null error!" );
                return false;
            }

            if ( m_BaseMap == newBaseMap )
                return SetLocation( newLocation );
            else
            {
                Point3D oldLocation = m_Location;
                BaseMap oldBaseMap = m_BaseMap;

                if ( OnBeforeMoveToWorld( newLocation, newBaseMap ) == false )
                    return false;
                else
                {
                    if ( UpdateMobile( UpdateBaseMobileValue.Map, newBaseMap ) == false )
                        return false;

                    if ( UpdateMobile( UpdateBaseMobileValue.Location, newLocation ) == false )
                        return false;
                }

                oldBaseMap.OnLeave( this );
                m_BaseMap.OnEnter( this );

                l_MobileDelta.UpdateMoveToWorldCall();
                if ( l_MobileDelta.IsDeltaMoveToWorldCall )
                    UpdateDelta();

                OnAfterMoveToWorld( oldLocation, oldBaseMap );

                return true;
            }
        }
        #endregion

        #endregion

        #endregion

        #region zh-CHS Direction属性 | en Public Properties

        #region zh-CHS 私有成员变量 | en Private Member Variables
        /// <summary>
        /// 人物所面向的方向
        /// </summary>
        private long m_Direction;
        #endregion
        /// <summary>
        /// 人物所面向的方向
        /// </summary>
        [CommandProperty( AccessLevel.GameMaster )]
        public long Direction
        {
            get { return m_Direction; }
            set { UpdateMobile( UpdateBaseMobileValue.Direction, value ); }
        }

        #endregion

        #region zh-CHS Serial属性 | en Public Properties

        #region zh-CHS 私有成员变量 | en Private Member Variables
        /// <summary>
        /// 人物所定义的唯一序号GUID
        /// </summary>
        private Serial m_Serial = new Serial();
        #endregion
        /// <summary>
        /// 人物所定义的唯一序号GUID
        /// </summary>
        [CommandProperty( AccessLevel.Counselor )]
        public Serial Serial
        {
            get { return m_Serial; }
            set { UpdateMobile( UpdateBaseMobileValue.Serial, value ); }
        }

        #endregion

        #region zh-CHS Map属性 | en Public Properties

        #region zh-CHS 私有成员变量 | en Private Member Variables
        /// <summary>
        /// 人物所在的地图
        /// </summary>
        //private BaseMap m_BaseMap = BaseMap.NullMap;
        private BaseMap m_BaseMap = null;
        #endregion
        /// <summary>
        /// 人物所在的地图
        /// </summary>
        [CommandProperty( AccessLevel.Counselor, AccessLevel.GameMaster )]
        public BaseMap Map
        {
            get { return m_BaseMap; }
            set { UpdateMobile( UpdateBaseMobileValue.Map, value ); }
        }

        #endregion

        #region zh-CHS Player属性 | en Public Properties

        #region zh-CHS 私有成员变量 | en Private Member Variables
        /// <summary>
        /// 指示当前是否是玩家(true) 还是 NPC与怪物(false)
        /// </summary>
        private bool m_Player = false;
        #endregion
        /// <summary>
        /// 指示当前是否是玩家(true) 还是 NPC与怪物(false)
        /// </summary>
        [CommandProperty( AccessLevel.GameMaster, AccessLevel.Administrator )]
        public bool Player
        {
            get { return m_Player; }
            set { UpdateMobile( UpdateBaseMobileValue.Player, value ); }
        }

        #endregion

        #region zh-CHS Name属性 | en Public Properties

        #region zh-CHS 私有成员变量 | en Private Member Variables
        /// <summary>
        /// 人物的名字
        /// </summary>
        private string m_Name = string.Empty;
        #endregion
        /// <summary>
        /// 人物的名字
        /// </summary>
        [CommandProperty( AccessLevel.GameMaster, AccessLevel.Administrator )]
        public string Name
        {
            get { return m_Name; }
            set { UpdateMobile( UpdateBaseMobileValue.Name, value ); }
        }

        #endregion

        #region zh-CHS Hidden属性 | en Public Properties

        #region zh-CHS 私有成员变量 | en Private Member Variables
        /// <summary>
        /// 人物是否隐藏
        /// </summary>
        private bool m_Hidden = false;
        #endregion
        /// <summary>
        /// 人物是否隐藏(其他人看不见的)
        /// </summary>
        [CommandProperty( AccessLevel.GameMaster )]
        public virtual bool Hidden
        {
            get { return m_Hidden; }
            set { UpdateMobile( UpdateBaseMobileValue.Hidden, value ); }
        }

        #endregion

        #region zh-CHS NetState属性 | en Public Properties

        #region zh-CHS 私有成员变量 | en Private Member Variables
        /// <summary>
        /// 人物的网络状态
        /// </summary>
        private NetState m_NetState = null;
        #endregion
        /// <summary>
        /// 人物的网络状态
        /// </summary>
        public NetState NetState
        {
            get { return m_NetState; }
            set { UpdateMobile( UpdateBaseMobileValue.NetState, value ); }
        }

        #endregion

        #region zh-CHS AccessLevel属性 | en Public Properties

        #region zh-CHS 私有成员变量 | en Private Member Variables
        /// <summary>
        /// 人物的帐号等级
        /// </summary>
        private AccessLevel m_AccessLevel;
        #endregion
        /// <summary>
        /// 人物的帐号等级
        /// </summary>
        public AccessLevel AccessLevel
        {
            get { return m_AccessLevel; }
            set { UpdateMobile( UpdateBaseMobileValue.AccessLevel, value ); }
        }

        #endregion

        #region zh-CHS Alive属性 | en Public Properties

        #region zh-CHS 私有成员变量 | en Private Member Variables
        /// <summary>
        /// 人物是否在活着(true)或死亡(false)
        /// </summary>
        private bool m_Alive = true;
        #endregion
        /// <summary>
        /// 人物是否在活着(true)或死亡(false)
        /// </summary>
        [CommandProperty( AccessLevel.Counselor )]
        public virtual bool Alive
        {
            get { return m_Alive; }
        }

        #region zh-CHS 人物的死亡(Player/NPC/Monster) | en

        #region zh-CHS 保护方法 | en Protected Methods
        /// <summary>
        /// 人物被杀死时,死亡之前
        /// </summary>
        /// <returns></returns>
        protected virtual bool OnBeforeDeath( BaseCreature mobileKiller )
        {
            return true;
        }

        /// <summary>
        /// 人物死亡后时调用
        /// </summary>
        /// <param name="c"></param>
        protected virtual void OnAfterDeath()
        {
        }
        #endregion

        #region zh-CHS 共有方法 | en Public Methods

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public bool Death()
        {
            return Death( null );
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="mobileKiller"></param>
        /// <returns></returns>
        public bool Death( BaseCreature mobileKiller )
        {
            if ( m_Deleted && m_Alive == false )
                return false;

            BaseCreatureDelta l_MobileDelta = m_MobileDelta as BaseCreatureDelta;
            if ( l_MobileDelta == null )
            {
                Debug.WriteLine( "BaseMobile.Death(...) - l_MobileDelta == null error!" );
                return false;
            }

            if ( OnBeforeDeath( mobileKiller ) == false )
                return false;
            else
            {
                if ( UpdateMobile( UpdateBaseMobileValue.Alive, false ) == false )
                    return false;
            }

            l_MobileDelta.UpdateDeathCall();
            if ( l_MobileDelta.IsDeltaDeathCall )
                UpdateDelta();

            OnAfterDeath();

            return true;
        }
        #endregion

        #endregion

        #region zh-CHS 人物的复活(Player/NPC/Monster-刷出) | en

        #region zh-CHS 保护方法 | en Protected Methods
        /// <summary>
        /// 复活之前,检查是否允许复活
        /// </summary>
        protected virtual bool OnBeforeResurrect( BaseCreature mobileResurrect )
        {
            return true;
        }

        /// <summary>
        /// 复活之后
        /// </summary>
        protected virtual void OnAfterResurrect()
        {
        }
        #endregion

        #region zh-CHS 共有方法 | en Public Methods

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public bool Resurrect()
        {
            return Resurrect( null );
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="mobileResurrect"></param>
        /// <returns></returns>
        public bool Resurrect( BaseCreature mobileResurrect )
        {
            if ( m_Deleted && m_Alive == true )
                return false;

            BaseCreatureDelta l_MobileDelta = m_MobileDelta as BaseCreatureDelta;
            if ( l_MobileDelta == null )
            {
                Debug.WriteLine( "BaseMobile.Resurrect(...) - l_MobileDelta == null erroe!" );
                return false;
            }

            if ( OnBeforeResurrect( mobileResurrect ) == false )
                return false;
            else
            {
                if ( UpdateMobile( UpdateBaseMobileValue.Alive, true ) == false )
                    return false;
            }

            l_MobileDelta.UpdateResurrectCall();
            if ( l_MobileDelta.IsDeltaResurrectCall )
                UpdateDelta();

            OnAfterResurrect();

            return true;

        }
        #endregion

        #endregion

        #endregion

        #region zh-CHS Loots属性 | en Public Properties

        #region zh-CHS 私有成员变量 | en Private Member Variables
        /// <summary>
        /// 
        /// </summary>
        BaseTreasure[] m_Loots = null;
        #endregion
        /// <summary>
        /// 随机掉落的道具
        /// </summary>
        public BaseTreasure[] Loots
        {
            get { return m_Loots; }
            set { UpdateMobile( UpdateBaseMobileValue.Loots, value ); }
        }

        #region zh-CHS 共有方法 | en Public Methods

        /// <summary>
        /// 开始掉落随机的道具
        /// </summary>
        /// <returns></returns>
        public BaseItem[] GenerateLoot()
        {
            if ( m_Loots == null )
                return null;

            List<BaseItem> baseTreasureList = new List<BaseItem>();

            foreach ( BaseTreasure baseTreasure in m_Loots )
            {
                if ( baseTreasure.IsDrop() )
                {
                    BaseItem[] baseItemArray = baseTreasure.RandomDrop();
                    if ( baseItemArray != null )
                        baseTreasureList.AddRange( baseItemArray );
                }
            }

            if ( baseTreasureList.Count <= 0 )
                return null;
            else
                return baseTreasureList.ToArray();
        }

        #endregion

        #endregion

        #region zh-CHS MobileDelta属性 | en Public Properties

        #region zh-CHS 私有成员变量 | en Private Member Variables
        /// <summary>
        /// 人物的状态机
        /// </summary>
        private ICreatureDelta m_MobileDelta = new BaseCreatureDelta();
        #endregion
        /// <summary>
        /// 人物的状态机
        /// </summary>
        public ICreatureDelta MobileDelta
        {
            get { return m_MobileDelta; }
        }

        /// <summary>
        /// BaseMobile人物的状态机(同 MobileDelta)
        /// </summary>
        public BaseCreatureDelta BaseMobileDelta
        {
            get { return m_MobileDelta as BaseCreatureDelta; }
        }

        #endregion

        #region zh-CHS Deleted属性 | en Public Properties

        #region zh-CHS 私有成员变量 | en Private Member Variables
        /// <summary>
        /// 人物是否删除
        /// </summary>
        private bool m_Deleted = false;
        #endregion
        /// <summary>
        /// BaseMobile是否已无效删除
        /// </summary>
        public bool Deleted
        {
            get { return m_Deleted; }
        }

        #region zh-CHS 人物的删除 | en

        #region zh-CHS 内部保护方法 | en Protected Internal Methods
        /// <summary>
        /// 在人物删除前
        /// </summary>
        protected virtual void OnBeforeDelete()
        {
        }

        /// <summary>
        /// 人物删除之后
        /// </summary>
        protected virtual void OnAfterDelete()
        {
        }
        #endregion

        #region zh-CHS 共有方法 | en Public Methods
        /// <summary>
        /// 删除
        /// </summary>
        public void Delete()
        {
            OnBeforeDelete();

            m_Deleted = true;

            OnAfterDelete();
        }
        #endregion

        #endregion

        #endregion

        #region zh-CHS 道具列表 属性 | en Public Properties

        #region zh-CHS 私有成员变量 | en Private Member Variables
        /// <summary>
        /// 人物的道具列表
        /// </summary>
        private Dictionary<long, BaseItem> m_ToteItems = new Dictionary<long, BaseItem>();
        /// <summary>
        /// 
        /// </summary>
        private object m_LockToteItems = new object();
        /// <summary>
        /// 全部好友
        /// </summary>
        private BaseItem[] m_ToteItemsArray = new BaseItem[0];
        /// <summary>
        /// 好友的集合数据是否已经改变过
        /// </summary>
        private bool m_bIsToteItemsChange = true;
        #endregion
        /// <summary>
        /// 人物的道具列表(包裹与身上)
        /// </summary>
        /// <returns></returns>
        [MultiThreadedWarningAttribute( "(道具)当前的数组是列表临时产生的,不能保存数组用于以后操作:警告!" )]
        public BaseItem[] ItemsToArray()
        {
            BaseItem[] l_BaseItem = null;

            Monitor.Enter( m_LockToteItems );
            {
                if ( m_bIsToteItemsChange )
                {
                    l_BaseItem = new BaseItem[m_ToteItems.Count];

                    long iIndex = 0;
                    foreach ( KeyValuePair<long, BaseItem> keyValuePair in m_ToteItems )
                    {
                        l_BaseItem[iIndex] = keyValuePair.Value;
                        iIndex++;
                    }

                    m_bIsToteItemsChange = false;
                }
            }
            Monitor.Exit( m_LockToteItems );

            return l_BaseItem;
        }

        #region zh-CHS 内部保护方法 | en Protected Internal Methods
        /// <summary>
        /// 道具添加
        /// </summary>
        /// <param name="item"></param>
        protected virtual bool OnBeforeAddItem( BaseItem baseItem )
        {
            return true;
        }

        /// <summary>
        /// 道具添加
        /// </summary>
        /// <param name="item"></param>
        protected virtual void OnAfterAddItem( BaseItem baseItem )
        {
        }

        /// <summary>
        /// 道具移去
        /// </summary>
        /// <param name="item"></param>
        protected virtual bool OnBeforeRemoveItem( BaseItem baseItem )
        {
            return true;
        }

        /// <summary>
        /// 道具移去
        /// </summary>
        /// <param name="item"></param>
        protected virtual void OnAfterRemoveItem( BaseItem baseItem )
        {
        }
        #endregion

        #region zh-CHS 共有方法 | en Public Methods

        /// <summary>
        /// 添加道具
        /// </summary>
        /// <param name="item"></param>
        public bool AddItem( BaseItem baseItem )
        {
            if ( m_Deleted )
                return false;

            if ( baseItem == null )
                return false;

            BaseCreatureDelta l_MobileDelta = m_MobileDelta as BaseCreatureDelta;
            if ( l_MobileDelta == null )
            {
                Debug.WriteLine( "BaseMobile.AddItem(...) - l_MobileDelta == null error!" );
                return false;
            }

            bool l_Return = false;
            Monitor.Enter( m_LockToteItems );
            do
            {
                BaseItem l_BaseItem = null;

                if ( m_ToteItems.TryGetValue( baseItem.Serial, out l_BaseItem ) )
                {
                    l_Return = true;
                    break;
                }

                if ( l_BaseItem != null )
                {
                    l_Return = true;
                    break;
                }

                if ( OnBeforeAddItem( baseItem ) == false )
                {
                    l_Return = true;
                    break;
                }

                m_ToteItems.Add( baseItem.Serial, baseItem );

                baseItem.Parent = this;

                m_bIsToteItemsChange = true;
            } while ( false );
            Monitor.Exit( m_LockToteItems );

            if ( l_Return )
                return false;

            l_MobileDelta.UpdateAddItemCall();
            if ( l_MobileDelta.IsDeltaAddItemCall )
                UpdateDelta();

            OnAfterAddItem( baseItem );

            return true;
        }

        /// <summary>
        /// 移出道具
        /// </summary>
        /// <param name="item"></param>
        public bool RemoveItem( long iItemSerial )
        {
            if ( m_Deleted )
                return false;

            BaseCreatureDelta l_MobileDelta = m_MobileDelta as BaseCreatureDelta;
            if ( l_MobileDelta == null )
            {
                Debug.WriteLine( "BaseMobile.RemoveItem(...) - l_MobileDelta == null error!" );
                return false;
            }

            bool l_Return = false;
            BaseItem l_BaseItem = null;
            Monitor.Enter( m_LockToteItems );
            do
            {
                if ( m_ToteItems.TryGetValue( iItemSerial, out l_BaseItem ) == false )
                {
                    l_Return = true;
                    break;
                }

                if ( l_BaseItem == null )
                {
                    l_Return = true;
                    break;
                }

                if ( OnBeforeRemoveItem( l_BaseItem ) == false )
                {
                    l_Return = true;
                    break;
                }

                m_ToteItems.Remove( iItemSerial );

                l_BaseItem.Parent = null;

                m_bIsToteItemsChange = true;
            } while ( false );
            Monitor.Exit( m_LockToteItems );

            if ( l_Return )
                return false;

            l_MobileDelta.UpdateRemoveItemCall();
            if ( l_MobileDelta.IsDeltaRemoveItemCall )
                UpdateDelta();

            OnAfterRemoveItem( l_BaseItem );

            return true;
        }

        /// <summary>
        /// 在身上找道具
        /// </summary>
        /// <param name="layer"></param>
        /// <returns></returns>
        public BaseItem[] FindItemOnLayer( Layer layer )
        {
            List<BaseItem> l_BaseItem = new List<BaseItem>();

            Monitor.Enter( m_LockToteItems );
            {
                foreach ( KeyValuePair<long, BaseItem> Item in m_ToteItems )
                {
                    if ( Item.Value.Deleted == false && Item.Value.Layer == layer )
                        l_BaseItem.Add( Item.Value );
                }
            }
            Monitor.Exit( m_LockToteItems );

            return l_BaseItem.ToArray();
        }

        /// <summary>
        /// 在身上找道具
        /// </summary>
        /// <param name="layer"></param>
        /// <returns></returns>
        public BaseItem FindItemOnSerial( long iItemSerial )
        {
            BaseItem l_BaseItem = null;

            Monitor.Enter( m_LockToteItems );
            {
                m_ToteItems.TryGetValue( iItemSerial, out l_BaseItem );
            }
            Monitor.Exit( m_LockToteItems );

            return l_BaseItem;
        }

        #endregion

        #endregion

        #region zh-CHS 好友列表 方法 | en Friend Method

        #region zh-CHS 私有成员变量 | en Private Member Variables
        /// <summary>
        /// 好友的集合
        /// </summary>
        private Dictionary<long, BaseCreature> m_BaseMobilesFriend = new Dictionary<long, BaseCreature>();
        /// <summary>
        /// 好友的集合锁
        /// </summary>
        private object m_LockBaseMobilesFriend = new object();
        /// <summary>
        /// 全部好友
        /// </summary>
        private BaseCreature[] m_MobileArrayFriend = new BaseCreature[0];
        /// <summary>
        /// 好友的集合数据是否已经改变过
        /// </summary>
        private bool m_bIsMobilesFriendChange = true;
        #endregion
        /// <summary>
        /// 全部好友的数组
        /// </summary>
        /// <returns></returns>
        [MultiThreadedWarningAttribute( "(好友)当前的数组是列表临时产生的,不能保存数组用于以后操作:警告!" )]
        public BaseCreature[] FriendToArray()
        {
            Monitor.Enter( m_LockBaseMobilesFriend );
            {
                if ( m_bIsMobilesFriendChange )
                {
                    m_MobileArrayFriend = new BaseCreature[m_BaseMobilesFriend.Count];

                    int iIndex = 0;
                    foreach ( KeyValuePair<long, BaseCreature> itemBaseMap in m_BaseMobilesFriend )
                    {
                        m_MobileArrayFriend[iIndex] = itemBaseMap.Value;
                        ++iIndex;
                    }

                    m_bIsMobilesFriendChange = false;
                }
            }
            Monitor.Exit( m_LockBaseMobilesFriend );

            return m_MobileArrayFriend;
        }

        #region zh-CHS 保护方法 | en Protected Methods
        /// <summary>
        /// 
        /// </summary>
        protected virtual bool OnBeforeAddFriend( BaseCreature newBaseMobile )
        {
            return true;
        }

        /// <summary>
        /// 
        /// </summary>
        protected virtual void OnAfterAddFriend( BaseCreature oldBaseMobile )
        {
        }

        /// <summary>
        /// 
        /// </summary>
        protected virtual bool OnBeforeRemoveFriend( BaseCreature newBaseMobile )
        {
            return true;
        }

        /// <summary>
        /// 
        /// </summary>
        protected virtual void OnAfterRemoveFriend( BaseCreature oldBaseMobile )
        {
        }
        #endregion

        #region zh-CHS 共有方法 | en Public Methods
        /// <summary>
        /// 添加好友到集合
        /// </summary>
        public bool AddFriend( BaseCreature baseMobile )
        {
            if ( m_Deleted )
                return false;

            if ( baseMobile == null )
                return false;

            BaseCreatureDelta l_MobileDelta = m_MobileDelta as BaseCreatureDelta;
            if ( l_MobileDelta == null )
            {
                Debug.WriteLine( "BaseMobile.AddFriend(...) - l_MobileDelta == null error!" );
                return false;
            }

            bool l_Return = false;
            Monitor.Enter( m_LockBaseMobilesFriend );
            do
            {
                BaseCreature l_baseMobile = null;

                if ( m_BaseMobilesFriend.TryGetValue( baseMobile.Serial, out l_baseMobile ) )
                {
                    l_Return = true;
                    break;
                }

                if ( l_baseMobile != null )
                {
                    l_Return = true;
                    break;
                }

                if ( OnBeforeAddFriend( baseMobile ) == false )
                {
                    l_Return = true;
                    break;
                }

                m_BaseMobilesFriend.Add( baseMobile.Serial, baseMobile );

                m_bIsMobilesFriendChange = true;
            } while ( false );
            Monitor.Exit( m_LockBaseMobilesFriend );

            if ( l_Return )
                return false;

            l_MobileDelta.UpdateAddFriendCall();
            if ( l_MobileDelta.IsDeltaAddFriendCall )
                UpdateDelta();

            OnAfterAddFriend( baseMobile );

            return true;
        }

        /// <summary>
        /// 在好友的集合内删除某好友
        /// </summary>
        /// <param name="iMapID"></param>
        public bool RemoveFriend( long iMobileSerial )
        {
            if ( m_Deleted )
                return false;

            BaseCreatureDelta l_MobileDelta = m_MobileDelta as BaseCreatureDelta;
            if ( l_MobileDelta == null )
            {
                Debug.WriteLine( "BaseMobile.RemoveFriend(...) - l_MobileDelta == null error!" );
                return false;
            }

            bool l_Return = false;
            BaseCreature l_BaseMobile = null;
            Monitor.Enter( m_LockBaseMobilesFriend );
            do
            {
                if ( m_BaseMobilesFriend.TryGetValue( iMobileSerial, out l_BaseMobile ) == false )
                {
                    l_Return = true;
                    break;
                }

                if ( l_BaseMobile == null )
                {
                    l_Return = true;
                    break;
                }

                if ( OnBeforeRemoveFriend( l_BaseMobile ) == false )
                {
                    l_Return = true;
                    break;
                }

                m_BaseMobilesFriend.Remove( iMobileSerial );

                m_bIsMobilesFriendChange = true;
            } while ( false );
            Monitor.Exit( m_LockBaseMobilesFriend );

            if ( l_Return )
                return false;

            l_MobileDelta.UpdateRemoveFriendCall();
            if ( l_MobileDelta.IsDeltaRemoveFriendCall )
                UpdateDelta();

            OnAfterRemoveFriend( l_BaseMobile );

            return true;
        }

        /// <summary>
        /// 在好友的集合内给出某好友
        /// </summary>
        /// <param name="iMapID"></param>
        /// <returns></returns>
        public BaseCreature GetFriend( long iMobileSerial )
        {
            BaseCreature l_BaseMobile = null;

            Monitor.Enter( m_LockBaseMobilesFriend );
            {
                m_BaseMobilesFriend.TryGetValue( iMobileSerial, out l_BaseMobile );
            }
            Monitor.Exit( m_LockBaseMobilesFriend );

            return l_BaseMobile;
        }
        #endregion

        #endregion

        #region zh-CHS 组队列表 方法 | en Group Method

        #region zh-CHS 私有成员变量 | en Private Member Variables
        /// <summary>
        /// 好友的集合
        /// </summary>
        private Dictionary<long, BaseCreature> m_BaseMobilesGroup = new Dictionary<long, BaseCreature>();
        /// <summary>
        /// 好友的集合锁
        /// </summary>
        private object m_LockBaseMobilesGroup = new object();
        /// <summary>
        /// 全部好友
        /// </summary>
        private BaseCreature[] m_MobileArrayGroup = new BaseCreature[0];
        /// <summary>
        /// 好友的集合数据是否已经改变过
        /// </summary>
        private bool m_bIsMobilesGroupChange = true;
        #endregion
        /// <summary>
        /// 全部好友的数组
        /// </summary>
        /// <returns></returns>
        [MultiThreadedWarningAttribute( "(组队)当前的数组是列表临时产生的,不能保存数组用于以后操作:警告!" )]
        public BaseCreature[] GroupToArray()
        {
            Monitor.Enter( m_bIsMobilesGroupChange );
            {
                if ( m_bIsMobilesGroupChange )
                {
                    m_MobileArrayGroup = new BaseCreature[m_BaseMobilesGroup.Count];

                    int iIndex = 0;
                    foreach ( KeyValuePair<long, BaseCreature> itemBaseMap in m_BaseMobilesGroup )
                    {
                        m_MobileArrayGroup[iIndex] = itemBaseMap.Value;
                        ++iIndex;
                    }

                    m_bIsMobilesGroupChange = false;
                }
            }
            Monitor.Exit( m_bIsMobilesGroupChange );

            return m_MobileArrayGroup;
        }

        #region zh-CHS 保护方法 | en Protected Methods
        /// <summary>
        /// 
        /// </summary>
        protected virtual bool OnBeforeAddGroup( BaseCreature newBaseMobile )
        {
            return true;
        }

        /// <summary>
        /// 
        /// </summary>
        protected virtual void OnAfterAddGroup( BaseCreature oldBaseMobile )
        {
        }

        /// <summary>
        /// 
        /// </summary>
        protected virtual bool OnBeforeRemoveGroup( BaseCreature newBaseMobile )
        {
            return true;
        }

        /// <summary>
        /// 
        /// </summary>
        protected virtual void OnAfterRemoveGroup( BaseCreature oldBaseMobile )
        {
        }
        #endregion

        #region zh-CHS 共有方法 | en Public Methods
        /// <summary>
        /// 添加好友到集合
        /// </summary>
        public bool AddGroup( Serial iMobileID, BaseCreature baseMobile )
        {
            if ( m_Deleted )
                return false;

            if ( baseMobile == null )
                return false;

            BaseCreatureDelta l_MobileDelta = m_MobileDelta as BaseCreatureDelta;
            if ( l_MobileDelta == null )
            {
                Debug.WriteLine( "BaseMobile.AddGroup(...) - l_MobileDelta == null error!" );
                return false;
            }

            bool l_Return = false;
            Monitor.Enter( m_LockBaseMobilesGroup );
            do
            {
                BaseCreature l_baseMobile = null;

                if ( m_BaseMobilesGroup.TryGetValue( baseMobile.Serial, out l_baseMobile ) )
                {
                    l_Return = true;
                    break;
                }

                if ( l_baseMobile != null )
                {
                    l_Return = true;
                    break;
                }

                if ( OnBeforeAddGroup( baseMobile ) == false )
                {
                    l_Return = true;
                    break;
                }

                m_BaseMobilesGroup.Add( baseMobile.Serial, baseMobile );

                m_bIsMobilesGroupChange = true;
            } while ( false );
            Monitor.Exit( m_LockBaseMobilesGroup );

            if ( l_Return )
                return false;

            l_MobileDelta.UpdateAddGroupCall();
            if ( l_MobileDelta.IsDeltaAddGroupCall )
                UpdateDelta();

            OnAfterAddGroup( baseMobile );

            return true;
        }

        /// <summary>
        /// 在好友的集合内删除某好友
        /// </summary>
        /// <param name="iMapID"></param>
        public bool RemoveGroup( long iMobileSerial )
        {
            if ( m_Deleted )
                return false;

            BaseCreatureDelta l_MobileDelta = m_MobileDelta as BaseCreatureDelta;
            if ( l_MobileDelta == null )
            {
                Debug.WriteLine( "BaseMobile.RemoveGroup(...) - l_MobileDelta == null error!" );
                return false;
            }

            bool l_Return = false;
            BaseCreature l_BaseMobile = null;
            Monitor.Enter( m_LockBaseMobilesGroup );
            do
            {
                if ( m_BaseMobilesGroup.TryGetValue( iMobileSerial, out l_BaseMobile ) == false )
                {
                    l_Return = true;
                    break;
                }

                if ( l_BaseMobile == null )
                {
                    l_Return = true;
                    break;
                }

                if ( OnBeforeRemoveGroup( l_BaseMobile ) == false )
                {
                    l_Return = true;
                    break;
                }

                m_BaseMobilesGroup.Remove( iMobileSerial );

                m_bIsMobilesGroupChange = true;
            } while ( false );
            Monitor.Exit( m_LockBaseMobilesGroup );

            if ( l_Return )
                return false;

            l_MobileDelta.UpdateRemoveGroupCall();
            if ( l_MobileDelta.IsDeltaRemoveGroupCall )
                UpdateDelta();

            OnAfterRemoveGroup( l_BaseMobile );

            return true;
        }

        /// <summary>
        /// 在好友的集合内给出某好友
        /// </summary>
        /// <param name="iMapID"></param>
        /// <returns></returns>
        public BaseCreature GetGroup( long iMobileSerial )
        {
            BaseCreature l_BaseMobile = null;

            Monitor.Enter( m_LockBaseMobilesGroup );
            {
                m_BaseMobilesGroup.TryGetValue( iMobileSerial, out l_BaseMobile );
            }
            Monitor.Exit( m_LockBaseMobilesGroup );

            return l_BaseMobile;
        }
        #endregion

        #endregion

        #region zh-CHS 团体列表 方法 | en Party Method

        #region zh-CHS 私有成员变量 | en Private Member Variables
        /// <summary>
        /// 好友的集合
        /// </summary>
        private Dictionary<long, BaseCreature> m_BaseMobilesParty = new Dictionary<long, BaseCreature>();
        /// <summary>
        /// 好友的集合锁
        /// </summary>
        private object m_LockBaseMobilesParty = new object();
        /// <summary>
        /// 全部好友
        /// </summary>
        private BaseCreature[] m_MobileArrayParty = new BaseCreature[0];
        /// <summary>
        /// 好友的集合数据是否已经改变过
        /// </summary>
        private bool m_bIsMobilesPartyChange = true;
        #endregion
        /// <summary>
        /// 全部好友的数组
        /// </summary>
        /// <returns></returns>
        [MultiThreadedWarningAttribute( "(团队)当前的数组是列表临时产生的,不能保存数组用于以后操作:警告!" )]
        public BaseCreature[] PartyToArray()
        {
            Monitor.Enter( m_LockBaseMobilesParty );
            {
                if ( m_bIsMobilesPartyChange )
                {
                    m_MobileArrayParty = new BaseCreature[m_BaseMobilesParty.Count];

                    int iIndex = 0;
                    foreach ( KeyValuePair<long, BaseCreature> itemBaseMap in m_BaseMobilesParty )
                    {
                        m_MobileArrayParty[iIndex] = itemBaseMap.Value;
                        ++iIndex;
                    }

                    m_bIsMobilesPartyChange = false;
                }
            }
            Monitor.Exit( m_LockBaseMobilesParty );

            return m_MobileArrayParty;
        }

        #region zh-CHS 保护方法 | en Protected Methods
        /// <summary>
        /// 
        /// </summary>
        protected virtual bool OnBeforeAddParty( BaseCreature newBaseMobile )
        {
            return true;
        }

        /// <summary>
        /// 
        /// </summary>
        protected virtual void OnAfterAddParty( BaseCreature oldBaseMobile )
        {
        }

        /// <summary>
        /// 
        /// </summary>
        protected virtual bool OnBeforeRemoveParty( BaseCreature newBaseMobile )
        {
            return true;
        }

        /// <summary>
        /// 
        /// </summary>
        protected virtual void OnAfterRemoveParty( BaseCreature oldBaseMobile )
        {
        }
        #endregion

        #region zh-CHS 共有方法 | en Public Methods
        /// <summary>
        /// 添加好友到集合
        /// </summary>
        public bool AddParty( Serial iMobileID, BaseCreature baseMobile )
        {
            if ( m_Deleted )
                return false;

            if ( baseMobile == null )
                return false;

            BaseCreatureDelta l_MobileDelta = m_MobileDelta as BaseCreatureDelta;
            if ( l_MobileDelta == null )
            {
                Debug.WriteLine( "BaseMobile.AddParty(...) - l_MobileDelta == null error!" );
                return false;
            }

            bool l_Return = false;
            Monitor.Enter( m_LockBaseMobilesParty );
            do
            {
                BaseCreature l_baseMobile = null;

                if ( m_BaseMobilesParty.TryGetValue( baseMobile.Serial, out l_baseMobile ) )
                {
                    l_Return = true;
                    break;
                }

                if ( l_baseMobile != null )
                {
                    l_Return = true;
                    break;
                }

                if ( OnBeforeAddParty( baseMobile ) == false )
                {
                    l_Return = true;
                    break;
                }

                m_BaseMobilesParty.Add( baseMobile.Serial, baseMobile );

                m_bIsMobilesPartyChange = true;
            } while ( false );
            Monitor.Exit( m_LockBaseMobilesParty );

            if ( l_Return )
                return false;

            l_MobileDelta.UpdateAddPartyCall();
            if ( l_MobileDelta.IsDeltaAddPartyCall )
                UpdateDelta();

            OnAfterAddParty( baseMobile );

            return true;
        }

        /// <summary>
        /// 在好友的集合内删除某好友
        /// </summary>
        /// <param name="iMapID"></param>
        public bool RemoveParty( long iMobileSerial )
        {
            if ( m_Deleted )
                return false;

            BaseCreatureDelta l_MobileDelta = m_MobileDelta as BaseCreatureDelta;
            if ( l_MobileDelta == null )
            {
                Debug.WriteLine( "BaseMobile.RemoveParty(...) - l_MobileDelta == null error!" );
                return false;
            }

            bool l_Return = false;
            BaseCreature l_BaseMobile = null;
            Monitor.Enter( m_LockBaseMobilesParty );
            do
            {
                if ( m_BaseMobilesParty.TryGetValue( iMobileSerial, out l_BaseMobile ) == false )
                {
                    l_Return = true;
                    break;
                }

                if ( l_BaseMobile == null )
                {
                    l_Return = true;
                    break;
                }

                if ( OnBeforeRemoveParty( l_BaseMobile ) == false )
                {
                    l_Return = true;
                    break;
                }

                m_BaseMobilesParty.Remove( iMobileSerial );

                m_bIsMobilesPartyChange = true;
            } while ( false );
            Monitor.Exit( m_LockBaseMobilesParty );

            if ( l_Return )
                return false;

            l_MobileDelta.UpdateRemovePartyCall();
            if ( l_MobileDelta.IsDeltaRemovePartyCall )
                UpdateDelta();

            OnAfterRemoveParty( l_BaseMobile );

            return true;
        }

        /// <summary>
        /// 在好友的集合内给出某好友
        /// </summary>
        /// <param name="iMapID"></param>
        /// <returns></returns>
        public BaseCreature GetParty( long iMobileSerial )
        {
            BaseCreature l_BaseMobile = null;

            Monitor.Enter( m_LockBaseMobilesParty );
            {
                m_BaseMobilesParty.TryGetValue( iMobileSerial, out l_BaseMobile );
            }
            Monitor.Exit( m_LockBaseMobilesParty );

            return l_BaseMobile;
        }

        #endregion

        #endregion

        #region zh-CHS CreationTime 属性 | en Public Properties

        #region zh-CHS 私有成员变量 | en Private Member Variables
        /// <summary>
        /// 人物实例产生的时间
        /// </summary>
        private DateTime m_CreationTime = DateTime.Now;
        #endregion
        /// <summary>
        /// 实例人物时产生的时间
        /// </summary>
        [CommandProperty( AccessLevel.GameMaster )]
        public DateTime CreationTime
        {
            get { return m_CreationTime; }
        }

        #endregion

        #region zh-CHS Sector属性 | en Public Properties

        #region zh-CHS 私有成员变量 | en Private Member Variables
        /// <summary>
        /// 
        /// </summary>
        private Sector m_Sector = Sector.NullSector;
        #endregion
        /// <summary>
        /// 用于内部使用的地图点
        /// </summary>
        internal Sector Sector
        {
            get { return m_Sector; }
            set { m_Sector = value; }
        }

        #endregion

        #region zh-CHS ISpawner属性 | en Public Properties
        #region zh-CHS 私有静态成员变量 | en Private Static Member Variables
        /// <summary>
        /// 
        /// </summary>
        private ISpawner m_Spawner = null;
        #endregion
        /// <summary>
        /// 
        /// </summary>
        public ISpawner Spawner
        {
            get { return m_Spawner; }
            set { m_Spawner = value; }
        }
        #endregion

        #region zh-CHS IMobileAI属性 | en Public Properties
        #region zh-CHS 私有静态成员变量 | en Private Static Member Variables
        /// <summary>
        /// 
        /// </summary>
        private ICreatureAI m_MobileAI = null;
        #endregion
        /// <summary>
        /// 
        /// </summary>
        public ICreatureAI MobileAI
        {
            get { return m_MobileAI; }
            set { m_MobileAI = value; }
        }
        #endregion

        #region zh-CHS Saving属性 | en Public Properties
        #region zh-CHS 私有成员变量 | en Private Member Variables
        /// <summary>
        /// 
        /// </summary>
        private bool m_Saving = false;
        #endregion
        /// <summary>
        /// 是否正在存储数据中
        /// </summary>
        public bool Saving
        {
            get { return m_Saving; }
        }
        #endregion

        #endregion

        #region zh-CHS 共有静态属性 | en Public Static Properties

        #region zh-CHS 私有成员变量 | en Private Member Variables
        /// <summary>
        /// 
        /// </summary>
        private static char[] m_GhostChars = new char[2] { 'o', 'O' };
        #endregion
        /// <summary>
        /// 人物的处理变异话语的数据
        /// </summary>
        public static char[] GhostChars
        {
            get { return m_GhostChars; }
            set { m_GhostChars = value; }
        }

        #region zh-CHS 人物的说话 | en

        #region zh-CHS 内部保护方法 | en Protected Internal Methods
        /// <summary>
        /// 检测是否可以听到变异的话
        /// </summary>
        /// <param name="m"></param>
        /// <param name="context"></param>
        /// <returns></returns>
        protected virtual bool OnCheckHearsMutatedSpeech( BaseCreature baseMobile, ref object context )
        {
            return true;
        }
        #endregion

        #region zh-CHS 共有方法 | en Public Methods
        /// <summary>
        /// 变异说的话
        /// </summary>
        /// <param name="hears">听得到的人的列表</param>
        /// <param name="text"></param>
        /// <param name="context"></param>
        /// <returns>变异说的话</returns>
        public string MutateSpeech( BaseCreature[] baseMobileHears, out bool[] CheckHears, string strText, ref object objectContext )
        {
            CheckHears = new bool[baseMobileHears.Length];

            int iIndex = 0;
            foreach ( BaseCreature baseMobile in baseMobileHears )
            {
                CheckHears[iIndex] = OnCheckHearsMutatedSpeech( baseMobile, ref objectContext );
                ++iIndex;
            }

            StringBuilder l_StringBuilder = new StringBuilder( strText.Length, strText.Length );

            foreach ( char charText in strText )
            {
                if ( charText != ' ' )
                    l_StringBuilder.Append( m_GhostChars[Utility.Random( m_GhostChars.Length )] );
                else
                    l_StringBuilder.Append( ' ' );
            }

            return l_StringBuilder.ToString();
        }
        #endregion

        #endregion

        #endregion

        #region zh-CHS 共有方法 | en Public Methods

        #region zh-CHS 人物可见的范围 | en

        #region zh-CHS 给出目标的距离 | en
        /// <summary>
        /// 给出目标的距离
        /// </summary>
        /// <param name="m"></param>
        /// <returns></returns>
        public double GetDistanceToSqrt( BaseCreature baseMobile )
        {
            if ( baseMobile == null )
            {
                Debug.WriteLine( "BaseMobile.GetDistanceToSqrt(...) - baseMobile == null error!" );

                return 0.0f;
            }

            return GetDistanceToSqrt( baseMobile as IPoint2D );
        }

        /// <summary>
        /// 给出目标的距离
        /// </summary>
        /// <param name="m"></param>
        /// <returns></returns>
        public double GetDistanceToSqrt( BaseItem baseItem )
        {
            if ( baseItem == null )
            {
                Debug.WriteLine( "BaseMobile.GetDistanceToSqrt(...) - baseItem == null error!" );

                return 0.0f;
            }

            return GetDistanceToSqrt( baseItem as IPoint2D );
        }

        /// <summary>
        /// 给出目标的距离
        /// </summary>
        /// <param name="p"></param>
        /// <returns></returns>
        public double GetDistanceToSqrt( Point3D point3D )
        {
            return GetDistanceToSqrt( point3D as IPoint2D );
        }

        /// <summary>
        /// 给出目标的距离
        /// </summary>
        /// <param name="p"></param>
        /// <returns></returns>
        public double GetDistanceToSqrt( IPoint3D point3D )
        {
            return GetDistanceToSqrt( point3D as IPoint2D );
        }

        /// <summary>
        /// 给出目标的距离
        /// </summary>
        /// <param name="p"></param>
        /// <returns></returns>
        public double GetDistanceToSqrt( Point2D point2D )
        {
            return GetDistanceToSqrt( point2D as IPoint2D );
        }

        /// <summary>
        /// 给出目标的距离
        /// </summary>
        /// <param name="p"></param>
        /// <returns></returns>
        public double GetDistanceToSqrt( IPoint2D point2D )
        {
            long xDelta = m_Location.X - point2D.X;
            long yDelta = m_Location.Y - point2D.Y;

            return Math.Sqrt( ( xDelta * xDelta ) + ( yDelta * yDelta ) );
        }
        #endregion

        #region zh-CHS 给出人物范围内的道具或人物或对象 | en
        /// <summary>
        /// 给出人物范围内的道具
        /// </summary>
        /// <param name="range"></param>
        /// <returns></returns>
        public IPooledEnumerable GetItemsInRange( int iRange )
        {
            if ( m_BaseMap == null || m_BaseMap == BaseMap.NullMap )
                return NullEnumerable.Instance;

            return m_BaseMap.GetItemsInRange( m_Location, iRange );
        }

        /// <summary>
        /// 给出人物范围内的对象
        /// </summary>
        /// <param name="range"></param>
        /// <returns></returns>
        public IPooledEnumerable GetObjectsInRange( int iRange )
        {
            if ( m_BaseMap == null || m_BaseMap == BaseMap.NullMap )
                return NullEnumerable.Instance;

            return m_BaseMap.GetObjectsInRange( m_Location, iRange );
        }

        /// <summary>
        /// 给出人物范围内的人物
        /// </summary>
        /// <param name="range"></param>
        /// <returns></returns>
        public IPooledEnumerable GetMobilesInRange( int iRange )
        {
            if ( m_BaseMap == null || m_BaseMap == BaseMap.NullMap )
                return NullEnumerable.Instance;

            return m_BaseMap.GetMobilesInRange( m_Location, iRange );
        }

        /// <summary>
        /// 给出人物范围内的客户端
        /// </summary>
        /// <param name="range"></param>
        /// <returns></returns>
        public IPooledEnumerable GetClientsInRange( int iRange )
        {
            if ( m_BaseMap == null || m_BaseMap == BaseMap.NullMap )
                return NullEnumerable.Instance;

            return m_BaseMap.GetClientsInRange( m_Location, iRange );
        }
        #endregion

        #region zh-CHS 给出人物或道具或位置是否在此人物的范围内 | en
        /// <summary>
        /// 人物是否在范围内
        /// </summary>
        /// <param name="p"></param>
        /// <param name="range"></param>
        /// <returns></returns>
        public bool InRange( BaseCreature baseMobile, int iRange )
        {
            if ( baseMobile == null )
            {
                Debug.WriteLine( "BaseMobile.InRange(...) - baseMobile == null error!" );

                return false;
            }

            return InRange( baseMobile as IPoint2D, iRange );
        }

        /// <summary>
        /// 道具是否在范围内
        /// </summary>
        /// <param name="p"></param>
        /// <param name="range"></param>
        /// <returns></returns>
        public bool InRange( BaseItem baseItem, int iRange )
        {
            if ( baseItem == null )
            {
                Debug.WriteLine( "BaseMobile.InRange(...) - baseItem == null error!" );

                return false;
            }

            return InRange( baseItem as IPoint2D, iRange );
        }

        /// <summary>
        /// 位置是否在范围内
        /// </summary>
        /// <param name="p"></param>
        /// <param name="range"></param>
        /// <returns></returns>
        public bool InRange( Point3D point3D, int iRange )
        {
            return InRange( point3D as IPoint2D, iRange );
        }

        /// <summary>
        /// 位置是否在范围内
        /// </summary>
        /// <param name="p"></param>
        /// <param name="range"></param>
        /// <returns></returns>
        public bool InRange( IPoint3D point3D, int iRange )
        {
            return InRange( point3D as IPoint2D, iRange );
        }

        /// <summary>
        /// 位置是否在范围内
        /// </summary>
        /// <param name="p"></param>
        /// <param name="range"></param>
        /// <returns></returns>
        public bool InRange( Point2D point2D, int iRange )
        {
            return InRange( point2D as IPoint2D, iRange );
        }

        /// <summary>
        /// 位置是否在范围内
        /// </summary>
        /// <param name="p"></param>
        /// <param name="range"></param>
        /// <returns></returns>
        public bool InRange( IPoint2D point2D, int iRange )
        {
            return ( point2D.X >= ( m_Location.X - iRange ) )
                && ( point2D.X <= ( m_Location.X + iRange ) )
                && ( point2D.Y >= ( m_Location.Y - iRange ) )
                && ( point2D.Y <= ( m_Location.Y + iRange ) );
        }
        #endregion

        #region zh-CHS 给出人物或道具是否可被此人物看见 | en

        #region zh-CHS 保护方法 | en Protected Methods
        /// <summary>
        /// 
        /// </summary>
        /// <param name="baseItem"></param>
        /// <returns></returns>
        protected virtual bool OnCanSee( BaseItem baseItem )
        {
            return true;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="baseMobile"></param>
        /// <returns></returns>
        protected virtual bool OnCanSee( BaseCreature baseMobile )
        {
            return true;
        }
        #endregion

        #region zh-CHS 共有方法 | en Public Methods
        /// <summary>
        /// 能否看见
        /// </summary>
        /// <param name="item"></param>
        /// <returns></returns>
        public virtual bool CanSee( BaseItem baseItem )
        {
            if ( baseItem == null )
            {
                Debug.WriteLine( "BaseMobile.CanSee(...) - baseItem == null error!" );

                return false;
            }

            if (  m_Deleted || baseItem.Deleted )
                return false;

            if ( m_BaseMap == null || baseItem.Map == null )
                return false;

            if ( m_BaseMap == BaseMap.NullMap || baseItem.Map == BaseMap.NullMap )
                return false;

            if ( baseItem.Parent != null )
            {
                BaseItem l_BaseItem = baseItem.Parent as BaseItem;
                if ( l_BaseItem != null )
                    return CanSee( l_BaseItem );

                BaseCreature l_BaseMobile = baseItem.Parent as BaseCreature;
                if ( l_BaseMobile != null )
                    return CanSee( l_BaseMobile );

                return false;
            }

            if ( baseItem.Map == m_BaseMap && baseItem.Visible )
                return OnCanSee( baseItem );

            return false;
        }

        /// <summary>
        /// 能否看见
        /// </summary>
        /// <param name="m"></param>
        /// <returns></returns>
        public virtual bool CanSee( BaseCreature baseMobile )
        {
            if ( baseMobile == null )
            {
                Debug.WriteLine( "BaseMobile.CanSee(...) - baseMobile == null error!" );

                return false;
            }

            if ( m_Deleted || baseMobile.m_Deleted )
                return false;

            if ( m_BaseMap == null || baseMobile.m_BaseMap == null )
                return false;

            if ( m_BaseMap == BaseMap.NullMap || baseMobile.m_BaseMap == BaseMap.NullMap )
                return false;

            if ( baseMobile.m_BaseMap == m_BaseMap && ( baseMobile.m_Hidden == false && baseMobile.m_Alive ) )
                return OnCanSee( baseMobile );

            return false;
        }
        #endregion

        #endregion

        #endregion

        #region zh-CHS 跟新数据 | en Protected Methods

        #region zh-CHS 保护方法 | en Protected Methods
        /// <summary>
        /// 数据改变之前
        /// </summary>
        protected virtual bool OnBeforeChangeValue( UpdateBaseMobileValue updateMobile, object newValue )
        {
            switch ( updateMobile )
            {
                case UpdateBaseMobileValue.MobileDelta:
                    BaseCreatureDelta l_BaseMobileDelta = newValue as BaseCreatureDelta;
                    if ( l_BaseMobileDelta == null )
                    {
                        Debug.WriteLine( "BaseMobile.OnBeforeChange(...) - l_BaseMobileDelta == null error!" );
                        return false;
                    }
                    break;
                default:

                    break;
            }
            return true;
        }

        /// <summary>
        /// 数据改变中
        /// </summary>
        protected virtual void OnValidateValue( UpdateBaseMobileValue updateMobile, object value )
        {
            switch ( updateMobile )
            {
                case UpdateBaseMobileValue.X:
                    m_Location.X = (long)value;

                    break;
                case UpdateBaseMobileValue.Y:
                    m_Location.Y = (long)value;

                    break;
                case UpdateBaseMobileValue.Z:
                    m_Location.Z = (long)value;

                    break;
                case UpdateBaseMobileValue.Location:
                    m_Location = (Point3D)value;

                    break;
                case UpdateBaseMobileValue.Direction:
                    m_Direction = (long)value;

                    break;
                case UpdateBaseMobileValue.Serial:
                    m_Serial = (Serial)value;

                    break;
                case UpdateBaseMobileValue.Map:
                    m_BaseMap = (BaseMap)value;

                    break;
                case UpdateBaseMobileValue.Player:
                    m_Player = (bool)value;

                    break;
                case UpdateBaseMobileValue.Name:
                    m_Name = (string)value;

                    break;
                case UpdateBaseMobileValue.Hidden:
                    m_Hidden = (bool)value;

                    break;
                case UpdateBaseMobileValue.NetState:
                    m_NetState = (NetState)value;

                    break;
                case UpdateBaseMobileValue.AccessLevel:
                    m_AccessLevel = (AccessLevel)value;

                    break;
                case UpdateBaseMobileValue.Alive:
                    m_Alive = (bool)value;

                    break;
                case UpdateBaseMobileValue.Loots:
                    m_Loots = (BaseTreasure[])value;

                    break;
                case UpdateBaseMobileValue.MobileDelta:
                    m_MobileDelta = value as BaseCreatureDelta;
                    
                    break;
                default:

                    break;
            }
        }

        /// <summary>
        /// 数据改变之后
        /// </summary>
        protected virtual void OnAfterChangeValue( UpdateBaseMobileValue updateMobile, object oldValue )
        {
        }
        #endregion

        #region zh-CHS 共有方法 | en Public Methods
        /// <summary>
        /// 更新全部类型的数量
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="type"></param>
        /// <param name="delta"></param>
        public bool UpdateMobile( UpdateBaseMobileValue updateMobile, object newValue )
        {
            if ( m_Deleted )
                return false;

            BaseCreatureDelta l_MobileDelta = m_MobileDelta as BaseCreatureDelta;
            if ( l_MobileDelta == null )
            {
                Debug.WriteLine( "BaseMobile.UpdateBaseMobile(...) - l_MobileDelta == null error!" );
                return false;
            }

            switch ( updateMobile )
            {
                case UpdateBaseMobileValue.X: // 当前地图的某个位置点改变
                    long oldValueX = m_Location.X;

                    if ( OnBeforeChangeValue( updateMobile, newValue ) == false )
                        return false;
                    else
                        OnValidateValue( updateMobile, newValue );

                    l_MobileDelta.UpdateX();
                    if ( l_MobileDelta.IsDeltaX )
                        UpdateDelta();

                    OnAfterChangeValue( updateMobile, oldValueX );

                    break;
                case UpdateBaseMobileValue.Y:
                    long oldValueY = m_Location.Y;

                    if ( OnBeforeChangeValue( updateMobile, newValue ) == false )
                        return false;
                    else
                        OnValidateValue( updateMobile, newValue );

                    l_MobileDelta.UpdateY();
                    if ( l_MobileDelta.IsDeltaY )
                        UpdateDelta();

                    OnAfterChangeValue( updateMobile, oldValueY );

                    break;
                case UpdateBaseMobileValue.Z:
                    long oldValueZ = m_Location.Y;

                    if ( OnBeforeChangeValue( updateMobile, newValue ) == false )
                        return false;
                    else
                        OnValidateValue( updateMobile, newValue );

                    l_MobileDelta.UpdateZ();
                    if ( l_MobileDelta.IsDeltaZ )
                        UpdateDelta();

                    OnAfterChangeValue( updateMobile, oldValueZ );

                    break;
                case UpdateBaseMobileValue.Location:
                    Point3D oldValueLocation = m_Location;

                    if ( OnBeforeChangeValue( updateMobile, newValue ) == false )
                        return false;
                    else
                        OnValidateValue( updateMobile, newValue );

                    l_MobileDelta.UpdateLocation();
                    if ( l_MobileDelta.IsDeltaLocation )
                        UpdateDelta();

                    OnAfterChangeValue( updateMobile, oldValueLocation );

                    break;
                case UpdateBaseMobileValue.Direction:
                    long oldValueDirection = m_Direction;

                    if ( OnBeforeChangeValue( updateMobile, newValue ) == false )
                        return false;
                    else
                        OnValidateValue( updateMobile, newValue );

                    l_MobileDelta.UpdateDirection();
                    if ( l_MobileDelta.IsDeltaDirection )
                        UpdateDelta();

                    OnAfterChangeValue( updateMobile, oldValueDirection );

                    break;
                case UpdateBaseMobileValue.Serial:
                    Serial oldValueSerial = m_Serial;

                    if ( OnBeforeChangeValue( updateMobile, newValue ) == false )
                        return false;
                    else
                        OnValidateValue( updateMobile, newValue );

                    l_MobileDelta.UpdateSerial();
                    if ( l_MobileDelta.IsDeltaSerial )
                        UpdateDelta();

                    OnAfterChangeValue( updateMobile, oldValueSerial );

                    break;
                case UpdateBaseMobileValue.Map:
                    //m_BaseMap = (BaseMap)value;

                    break;
                case UpdateBaseMobileValue.Player:
                    bool oldValuePlayer = m_Player;

                    if ( OnBeforeChangeValue( updateMobile, newValue ) == false )
                        return false;
                    else
                        OnValidateValue( updateMobile, newValue );

                    l_MobileDelta.UpdatePlayer();
                    if ( l_MobileDelta.IsDeltaPlayer )
                        UpdateDelta();

                    OnAfterChangeValue( updateMobile, oldValuePlayer );

                    break;
                case UpdateBaseMobileValue.Name:
                    string oldValueName = m_Name;

                    if ( OnBeforeChangeValue( updateMobile, newValue ) == false )
                        return false;
                    else
                        OnValidateValue( updateMobile, newValue );

                    l_MobileDelta.UpdateName();
                    if ( l_MobileDelta.IsDeltaName )
                        UpdateDelta();

                    OnAfterChangeValue( updateMobile, oldValueName );

                    break;
                case UpdateBaseMobileValue.Hidden:
                    bool oldValueHidden = m_Hidden;

                    if ( OnBeforeChangeValue( updateMobile, newValue ) == false )
                        return false;
                    else
                        OnValidateValue( updateMobile, newValue );

                    l_MobileDelta.UpdateHidden();
                    if ( l_MobileDelta.IsDeltaHidden )
                        UpdateDelta();

                    OnAfterChangeValue( updateMobile, oldValueHidden );

                    break;
                case UpdateBaseMobileValue.NetState:
                    NetState oldValueNetState = m_NetState;

                    if ( OnBeforeChangeValue( updateMobile, newValue ) == false )
                        return false;
                    else
                        OnValidateValue( updateMobile, newValue );

                    l_MobileDelta.UpdateNetState();
                    if ( l_MobileDelta.IsDeltaNetState )
                        UpdateDelta();

                    OnAfterChangeValue( updateMobile, oldValueNetState );

                    break;
                case UpdateBaseMobileValue.AccessLevel:
                    AccessLevel oldValueAccessLevel = m_AccessLevel;

                    if ( OnBeforeChangeValue( updateMobile, newValue ) == false )
                        return false;
                    else
                        OnValidateValue( updateMobile, newValue );

                    l_MobileDelta.UpdateAccessLevel();
                    if ( l_MobileDelta.IsDeltaAccessLevel )
                        UpdateDelta();

                    OnAfterChangeValue( updateMobile, oldValueAccessLevel );

                    break;
                case UpdateBaseMobileValue.Alive:
                    bool oldValueAlive = m_Alive;

                    if ( OnBeforeChangeValue( updateMobile, newValue ) == false )
                        return false;
                    else
                        OnValidateValue( updateMobile, newValue );

                    l_MobileDelta.UpdateAlive();
                    if ( l_MobileDelta.IsDeltaAlive )
                        UpdateDelta();

                    OnAfterChangeValue( updateMobile, oldValueAlive );

                    break;
                case UpdateBaseMobileValue.Loots:
                    BaseTreasure[] oldValueLoots = m_Loots;

                    if ( OnBeforeChangeValue( updateMobile, newValue ) == false )
                        return false;
                    else
                        OnValidateValue( updateMobile, newValue );

                    l_MobileDelta.UpdateLoots();
                    if ( l_MobileDelta.IsDeltaLoots )
                        UpdateDelta();

                    OnAfterChangeValue( updateMobile, oldValueLoots );

                    break;
                case UpdateBaseMobileValue.MobileDelta:
                    ICreatureDelta oldValueMobileDelta = m_MobileDelta;

                    if ( OnBeforeChangeValue( updateMobile, newValue ) == false )
                        return false;
                    else
                        OnValidateValue( updateMobile, newValue );

                    l_MobileDelta.UpdateMobileDelta();
                    if ( l_MobileDelta.IsDeltaMobileDelta )
                        UpdateDelta();

                    OnAfterChangeValue( updateMobile, oldValueMobileDelta );

                    break;
                default:

                    break;
            }


            return true;
        }
        #endregion

        #endregion

        #region zh-CHS 保存数据 | en Protected Methods

        #region zh-CHS 保护方法 | en Protected Methods
        #region zh-CHS 私有成员变量 | en Private Member Variables
        /// <summary>
        /// 
        /// </summary>
        private object m_LockSave = new object();
        #endregion
        /// <summary>
        /// 保存移动物体
        /// </summary>
        protected internal void OnSave()
        {
            // 移动物体的数据必须要成功才返回
            Monitor.Enter( m_LockSave );
            {
                // 保存数据中......
                m_Saving = true;

                LOGs.WriteLine( LogMessageType.MSG_NOTICE, "移动物体: 开始保存移动物体({0})数据中......", m_Name );

                // 保存数据
                if ( EventSaveMobile != null )
                {
                    BaseMobileEventArgs l_EventArgs = new BaseMobileEventArgs( this );
                    EventSaveMobile( l_EventArgs );
                }

                LOGs.WriteLine( LogMessageType.MSG_NOTICE, "移动物体: 移动物体({0})数据保存完毕.", m_Name );

                // 保存数据结束......
                m_Saving = false;
            }
            Monitor.Exit( m_LockSave );
        }
        #endregion

        #region zh-CHS 共有方法 | en Public Methods
        /// <summary>
        /// 移动物体的数据
        /// </summary>
        public void Save()
        {
            OnSave();
        }
        #endregion

        #endregion

        #region zh-CHS 创建一个新的自身人物 | en Method
        #region zh-CHS 私有成员变量 | en Private Member Variables
        /// <summary>
        /// 
        /// </summary>
        private ConstructorInfo m_ConstructorInfo = null;
        #endregion
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public object CreateNewInstance()
        {
            if ( m_ConstructorInfo != null )
            {
                object l_ReturnObject = m_ConstructorInfo.Invoke( null );

                BaseCreature l_BaseMobile = l_ReturnObject as BaseCreature;
                if ( l_BaseMobile == null )
                {
                    Debug.WriteLine( "BaseMobile.CreateNewInstance(...) - l_BaseMobile == null error!" );
                    return null;
                }

                return l_ReturnObject;
            }

            Type l_Type = GetType();
            ConstructorInfo[] l_ConstructorInfoArray = l_Type.GetConstructors();

            foreach ( ConstructorInfo l_ConstructorInfo in l_ConstructorInfoArray )
            {
                ParameterInfo[] l_ParameterInfoArray = l_ConstructorInfo.GetParameters();
                if ( l_ParameterInfoArray.Length == 0 )
                {
                    m_ConstructorInfo = l_ConstructorInfo;

                    object l_ReturnObject = m_ConstructorInfo.Invoke( null );

                    BaseCreature l_BaseMobile = l_ReturnObject as BaseCreature;
                    if ( l_BaseMobile == null )
                    {
                        Debug.WriteLine( "BaseMobile.CreateNewInstance(...) - l_BaseMobile == null error!" );
                        return null;
                    }

                    return l_ReturnObject;
                }
            }

            return null;
        }
        #endregion

        #region zh-CHS 人物的主处理行为 | en
        /// <summary>
        /// 
        /// </summary>
        /// <param name="flag"></param>
        protected void UpdateDelta()
        {
            if ( m_MobileDelta == null || m_BaseMap == null || m_BaseMap == BaseMap.NullMap || m_Deleted )
                return;

            if ( m_MobileDelta.LoginDeltaQueue() == false )
                return;

            Monitor.Enter( s_LockDeltaQueue );
            {
                s_DeltaQueue.Enqueue( this );
            }
            Monitor.Exit( s_LockDeltaQueue );

            //BaseWorld.SetSignal();
        }

        /// <summary>
        /// 
        /// </summary>
        protected virtual void ProcessDelta()
        {
        }
        #endregion

        #endregion

        #region zh-CHS 共有静态方法 | en Public Static Methods

        #region zh-CHS 私有静态成员变量 | en Private Static Member Variables
        /// <summary>
        /// 
        /// </summary>
        private static Queue<BaseCreature> s_DeltaQueue = new Queue<BaseCreature>();
        /// <summary>
        /// 
        /// </summary>
        private static object s_LockDeltaQueue = new object();
        #endregion
        /// <summary>
        /// 处理Delta
        /// </summary>
        public static void ProcessDeltaQueue()
        {
            // 使用数组减少锁定时间
            BaseCreature[] baseMobileArray = null;

            if ( Monitor.TryEnter( s_LockDeltaQueue ) == false ) return;
            {
                if ( s_DeltaQueue.Count > 0 )
                {
                    baseMobileArray = s_DeltaQueue.ToArray();
                    s_DeltaQueue.Clear();
                }
            }
            Monitor.Exit( s_LockDeltaQueue );

            // 如果没有需要处理的数据则返回
            if ( baseMobileArray == null )
                return;

            foreach ( BaseCreature baseMobile in baseMobileArray )
            {
                baseMobile.MobileDelta.LogoutDeltaQueue();
                baseMobile.ProcessDelta();
            }
        }

        #endregion

        #region zh-CHS 接口实现 | en Interface Implementation

        /// <summary>
        /// 
        /// </summary>
        /// <param name="other"></param>
        /// <returns></returns>
        public int CompareTo( IEntity other )
		{
			if( other == null )
				return 1;

            return m_Serial.CompareTo( other.Serial );
		}

        /// <summary>
        /// 
        /// </summary>
        /// <param name="other"></param>
        /// <returns></returns>
		public int CompareTo( BaseCreature other )
		{
            return CompareTo( other as IEntity );
		}

        /// <summary>
        /// 
        /// </summary>
        /// <param name="other"></param>
        /// <returns></returns>
		public int CompareTo( object xObject )
		{
            return CompareTo( xObject as IEntity );
        }

        #endregion

        #region zh-CHS 方法覆盖 | en Override Methods

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            return m_Name;
        }

        #endregion

        #region zh-CHS 共有事件 | en Public Event
        /// <summary>
        /// 
        /// </summary>
        public event SaveMobileEventHandler EventSaveMobile;
        #endregion
    }
}
#endregion